package cn.core.sign.task;

import cn.core.sign.eo.Sessions;
import cn.core.sign.mapper.SessionsMapper;
import cn.core.tool.context.CurrentContextData;
import cn.core.tool.util.CoreTool;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 定时任务 >>> 删除过期会话
 */
@Log4j2
@Component
@ConditionalOnProperty(prefix = "proconf", name = "remove-expire-session", havingValue = "true")
public class RemoveExpireSession {

  @Resource
  private Gson gson;

  @Resource
  private SessionsMapper sessionsMapper;

  @Value("${proconf.enable-session-redis}")
  private boolean enableSessionRedis;

  @Resource
  private StringRedisTemplate stringRedisTemplate;

  @Value("${proconf.session-redis-key-prefix}")
  private String sessionRedisKeyPrefix;

  @Scheduled(cron = "0 */1 * * * ?")
  public void RemoveExpireSessionRecord() throws Exception {
    try {
      long times = System.currentTimeMillis();
      Collection<Sessions> sessionsSet = sessionsMapper.query(null);
      LinkedHashSet<Sessions> delSessionSet = new LinkedHashSet<>();
      if (CoreTool.isNotEmpty(sessionsSet)) {
        for (Sessions eo : sessionsSet) {
          if (enableSessionRedis) {
            String redisTokenStr = stringRedisTemplate.opsForValue().get(sessionRedisKeyPrefix + eo.getId());
            if (redisTokenStr == null) {
              delSessionSet.add(eo);
            }
          } else {
            if ("Browser".equals(eo.getLoginSide())) {
              // 浏览器端登录
              CurrentContextData currentContextData = gson.fromJson(eo.getSessionsInfo(), new TypeToken<CurrentContextData>(){}.getType());
              if (eo.getCurrentTimes().longValue() + currentContextData.getTokenExpireBrowser().longValue() <= times) {
                delSessionSet.add(eo);
              }
            } else if ("Android".equals(eo.getLoginSide())) {
              // 安卓app登录
              CurrentContextData currentContextData = gson.fromJson(eo.getSessionsInfo(), new TypeToken<CurrentContextData>(){}.getType());
              if (eo.getCurrentTimes().longValue() + currentContextData.getTokenExpireAndroid().longValue() <= times) {
                delSessionSet.add(eo);
              }
            } else if ("ios".equals(eo.getLoginSide())) {
              // 苹果app登录
              CurrentContextData currentContextData = gson.fromJson(eo.getSessionsInfo(), new TypeToken<CurrentContextData>(){}.getType());
              if (eo.getCurrentTimes().longValue() + currentContextData.getTokenExpireIos().longValue() <= times) {
                delSessionSet.add(eo);
              }
            } else if ("Wechatapp".equals(eo.getLoginSide())) {
              // 微信小程序登录
              CurrentContextData currentContextData = gson.fromJson(eo.getSessionsInfo(), new TypeToken<CurrentContextData>(){}.getType());
              if (eo.getCurrentTimes().longValue() + currentContextData.getTokenExpireWechatapp().longValue() <= times) {
                delSessionSet.add(eo);
              }
            }
          }
        }
      }
      if (CoreTool.isNotEmpty(delSessionSet)) {
        sessionsMapper.removeBatchSessions(delSessionSet);
      }
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

}
